package org.jeecg.modules.flowable.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.modules.flowable.dto.BpmnModelDTO;
import org.jeecg.modules.flowable.entity.FlowCategory;
import org.jeecg.modules.flowable.entity.FlowModel;
import org.jeecg.modules.flowable.query.FlowModelQuery;
import org.jeecg.modules.flowable.query.FlowTaskQuery;
import org.jeecg.modules.flowable.service.FlowCategoryService;
import org.jeecg.modules.flowable.service.FlowModelService;
import org.jeecg.modules.flowable.vo.FlowModelVO;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

@Slf4j
@Api(tags = "流程模型")
@RestController
@RequiredArgsConstructor
@RequestMapping(value = "/flow/model")
public class FlowModelController {

    final FlowModelService flowModelService;

    final FlowCategoryService flowCategoryService;

    @AutoLog(value = "流程模型管理-通过id查询")
    @ApiOperation(value = "根据id查询流程模型", notes = "根据id查询流程模型")
    @GetMapping("/{id}")
    public Result<FlowModel> getById(@PathVariable String id) {
        return Result.OK(this.flowModelService.getById(id));
    }

    @AutoLog(value = "流程模型管理-添加")
    @ApiOperation(value = "添加流程模型", notes = "添加流程模型")
    @PostMapping
    public Result<Void> add(@RequestBody FlowModel model) {
        FlowCategory flowCategory = flowCategoryService.getById(model.getCategoryId());
        model.setCategoryName(flowCategory.getName());
        this.flowModelService.save(model);
        return Result.OK();
    }

    @AutoLog(value = "流程模型管理-修改")
    @ApiOperation(value = "修改流程模型", notes = "修改流程模型")
    @PutMapping
    public Result<Void> edit(@RequestBody FlowModel model) {
        FlowCategory flowCategory = flowCategoryService.getById(model.getCategoryId());
        model.setCategoryName(flowCategory.getName());
        this.flowModelService.updateById(model);
        return Result.OK();
    }

    @AutoLog(value = "流程模型管理-删除")
    @ApiOperation(value = "删除流程模型", notes = "删除流程模型")
    @DeleteMapping("/{id}")
    public Result<Void> delete(@PathVariable String id) {
        this.flowModelService.removeById(id);
        return Result.OK();
    }

    @AutoLog(value = "流程模型管理-列表查询")
    @ApiOperation(value = "列表查询流程模型", notes = "列表查询流程模型")
    @GetMapping("/list")
    public Result<List<FlowModel>> list() {
        return Result.OK(this.flowModelService.list());
    }

    @AutoLog(value = "流程模型管理-分页查询")
    @ApiOperation(value = "分页查询流程模型", notes = "分页查询流程模型")
    @GetMapping("/page")
    public Result<IPage<FlowModelVO>> page(FlowModelQuery query) {
        return Result.OK(this.flowModelService.getList(query));
    }

    @AutoLog(value = "流程模型管理-发布流程模型")
    @ApiOperation(value = "发布流程模型", notes = "发布流程模型")
    @GetMapping("/publish/{modeId}")
    public Result<Void> publish(@PathVariable String modeId) {
        return this.flowModelService.publish(modeId);
    }

    @AutoLog(value = "流程模型管理-导入流程模型")
    @ApiOperation(value = "导入流程模型", notes = "导入流程模型")
    @PostMapping("/import/bpmn-model")
    public Result<Void> importBpmnModel(@RequestBody BpmnModelDTO bpmnModel) {
        return this.flowModelService.importBpmnModel(bpmnModel);
    }

    @AutoLog(value = "流程模型管理-加载流程模型")
    @ApiOperation(value = "加载流程模型", notes = "加载流程模型")
    @GetMapping("/load/bpmn-xml/{modelId}")
    public Result<FlowModelVO> loadBpmnXmlByModelId(@PathVariable String modelId) {
        return this.flowModelService.loadBpmnXmlByModelId(modelId);
    }

    @ApiOperation(value = "激活或挂起流程模型")
    @PutMapping(value = "/updateState")
    public Result updateState(@ApiParam(value = "启用状态", required = true) @RequestParam Integer state,
                              @ApiParam(value = "流程模型编号", required = true) @RequestParam String id) {
        flowModelService.updateState(state, id);
        return Result.OK("操作成功");
    }

    @ApiOperation(value = "生成流程模型图")
    @GetMapping(value = "/img/{processDefinitionId}")
    public void genProcessDiagram(HttpServletResponse response, @PathVariable String processDefinitionId) throws IOException {
        InputStream inputStream = this.flowModelService.genProcessDiagram(processDefinitionId);
        response.setHeader("Content-type", "image/png");
        IOUtils.copy(inputStream, response.getOutputStream());
        inputStream.close();
    }

    @ApiOperation(value = "生成流程实例进度图")
    @GetMapping(value = "/schedule/img/{processInstanceId}")
    public void genProcessDiagramSchedule(HttpServletResponse response, @PathVariable String processInstanceId) throws IOException {
        InputStream inputStream = this.flowModelService.genProcessDiagramSchedule(processInstanceId);
        response.setHeader("Content-type", "image/png");
        IOUtils.copy(inputStream, response.getOutputStream());
        inputStream.close();
    }

    @ApiOperation(value = "生成流程实例进度图")
    @GetMapping(value = "/schedule/xml/{processInstanceId}")
    public void genProcessDiagramScheduleXml(HttpServletResponse response, @PathVariable String processInstanceId) throws IOException {
        InputStream inputStream = this.flowModelService.genProcessDiagramSchedule(processInstanceId);
        response.setHeader("Content-type", "text/xml;charset=UFT-8");
        IOUtils.copy(inputStream, response.getOutputStream());
        inputStream.close();
    }
}
